/*
*  Impp - Instant Messenger
*
*  Copyright (C) 2008  Oliver Schneider
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#include "PackageUtils.h"
#include <wx/regex.h>
#include <wx/log.h>

namespace Impp {

word toWord(byte* b2){
	word w(0);
    w |= *b2++;
	w <<= 8;
	w |= *b2;
	return w;
}

word swapBytes(word w){
	return (((w >> 8)) | (w << 8));
}

wxString byteToWxString(byte* data, size_t lng){
	/*
	char* tmp[lng+1];
	byteToString(data,(char*)tmp,lng);
	//std::cout << "Check: "<< (char*)tmp << std::endl;
	 */
	return wxString::FromUTF8((char*)(data),lng);

}

void toHex(std::ostream & out, byte* data,size_t lng){
	for(size_t i=0; i < lng-1; i++){
		toHex(out,data[i]);
		out << " ";
	}
	toHex(out,data[lng-1]);
}

void toHex(std::ostream & out, byte & b){
	if(b < 0x10){
		out << "0" << std::hex << (unsigned short)b;
	}else{
		out << std::hex << (unsigned short)b;
	}

}
void toHex(std::ostream & out, word  & w){
	if(w < 0x0010){
		out << "000" << std::hex << (unsigned short)w;
	}else if(w < 0x0100){
		out << "00" << std::hex << (unsigned short)w;
	}else if(w < 0x1000){
		out << "0" << std::hex << (unsigned short)w;
	}else {
		out  << std::hex << (unsigned short)w;
	}

}

Status icqStatusToStatus(ICQStatus status){
	Status retStatus;

	if((status & ICQ_STATUS_DND) != 0){
		retStatus = DND;
	}else if((status & ICQ_STATUS_OCCUPIED) != 0){
		retStatus =  OCCUPIED;
	}else if((status & ICQ_STATUS_NA) != 0){
		retStatus =  NA;
	}else if((status & ICQ_STATUS_AWAY) != 0){
		retStatus = AWAY;
	}else if((status & ICQ_STATUS_FREE4CHAT) != 0){
		retStatus = FREE4CHAT;
	}else if((status & ICQ_STATUS_OFFLINE) != 0){
		retStatus = OFFLINE;
	}else{
		retStatus = ONLINE;
	}

	if((status & ICQ_STATUS_INVISIBLE) != 0){
		retStatus.setFlag(INVISIBLE);
	}

	return retStatus;
}

void deleteAllocedTlv(Tlv* tlv){
	delete[] tlv->data;
}

void mewAllocedTlv(Tlv* tlv, const word & type, const byte* newValue, const word & newSize){
	tlv->type = type;
	tlv->data = new byte[newSize];
	tlv->length = newSize;
	memcpy(tlv->data,newValue,newSize);
}

void toAllocedTlv(Tlv* tlv){
	byte* oldData = tlv->data;
	tlv->data = new byte[tlv->length];
	memcpy(tlv->data,oldData,tlv->length);
}

ICQStatus toIcqStatus(Status status) {

	unsigned int icqStatus = ICQ_STATUS_ONLINE;

	if(status == ONLINE) icqStatus = ICQ_STATUS_ONLINE;
	else if(status == AWAY) icqStatus = ICQ_STATUS_AWAY;
	else if(status == DND) icqStatus = ICQ_STATUS_DND;
	else if(status == NA) icqStatus = ICQ_STATUS_NA;
	else if(status == OCCUPIED) icqStatus = ICQ_STATUS_OCCUPIED;
	else if(status == FREE4CHAT) icqStatus = ICQ_STATUS_FREE4CHAT;
	else if(status == OFFLINE) icqStatus = ICQ_STATUS_ONLINE;

	if(status == INVISIBLE){
		icqStatus |= ICQ_STATUS_INVISIBLE;
	}

	return (ICQStatus) icqStatus;

}

void removeHtml(wxString & s){
	//wxLogDebug(wxT("HTML : %s"), s.c_str());
	//wxLogDebug(wxT("before: %s"), s.c_str());

	s.Replace(wxT("<BR>"), wxT("\n"));
	//s.Replace(wxT("</DIV>"), wxT("\n"));

	wxRegEx reg(wxT("<IMG.+?src=\"([^\"]+)\"[^>]*>"), wxRE_ADVANCED|wxRE_ICASE);
	reg.ReplaceAll(&s,wxT("\\1"));

	wxRegEx reg2(wxT("</A>"));
	reg2.ReplaceAll(&s,wxT(" "));

	wxRegEx reg3(wxT("<[^>]*>"));
	reg3.ReplaceAll(&s,wxEmptyString);
	s.Replace(wxT("&lt;"),wxT("<"));
	s.Replace(wxT("&gt;"),wxT(">"));
	s.Replace(wxT("&quot;"),wxT("\""));
	s.Replace(wxT("&amp;"),wxT("&"));

	//wxLogDebug(wxT("after: %s"), s.c_str());
}

bool capEquals(byte* c1, byte* c2){
	for (size_t i = 0; i < 16; ++i) {
		if(c1[i]!=c2[i]){
			return false;
		}
	}
	return true;
}

wxString toHexString(byte* data, size_t lng){
	wxString hexString;
	wxString tmp;
	for (size_t i = 0; i < lng; ++i) {
		tmp =  wxString::Format(wxT("%X"),data[i]);
		if(tmp.Len() == 2){
			hexString << tmp;
		}else{
			hexString << wxT("0") << tmp;
		}
	}
	return hexString;

}

wxString ipToString(const dword & ip){
	Ip ipunion = ip;
	wxString ips = wxString::Format(wxT("%i.%i.%i.%i"),ipunion.part[3],ipunion.part[2],ipunion.part[1],ipunion.part[0]);
	return ips;

}

IpAndPort::IpAndPort(wxString serverAdressString){
	int pos = serverAdressString.Find(':');
	if(pos == wxNOT_FOUND){
		this->ip = serverAdressString;
		this->port = 5190;
	}else{
		this->ip = serverAdressString.SubString(0,pos-1);
		wxString portS = serverAdressString.SubString(pos+1,serverAdressString.size());
		portS.ToLong(&(this->port));
	}
}

}
